import java.io.*;
import java.util.*;

class Student {
    private String id;
    private String name;
    private Map<String, Double> grades;

    public Student(String id, String name) {
        this.id = id;
        this.name = name;
        this.grades = new HashMap<>();
    }

    public String getId() { return id; }
    public String getName() { return name; }

    public void addGrade(String courseCode, double score) {
        grades.put(courseCode, score);
    }

    public Map<String, Double> getGrades() { return grades; }

    public double calculateGPA() {
        double totalPoints = 0.0;
        for (double score : grades.values()) {
            totalPoints += convertScoreToGPA(score);
        }
        return grades.size() > 0 ? totalPoints / grades.size() : 0;
    }

    private double convertScoreToGPA(double score) {
        if (score >= 90) return 4.0;
        if (score >= 86) return 3.67;
        if (score >= 83) return 3.33;
        if (score >= 80) return 3.0;
        if (score >= 76) return 2.67;
        if (score >= 73) return 2.33;
        if (score >= 70) return 2.0;
        if (score >= 66) return 1.67;
        if (score >= 63) return 1.33;
        if (score >= 60) return 1.0;
        return 0.0;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(id).append(",").append(name);
        for (double score : grades.values()) {
            sb.append(",").append(score);
        }
        sb.append(",").append(calculateGPA());
        return sb.toString();
    }
}

class StudentManagementSystem {
    private List<Student> students;
    private static final String CSV_FILE_PATH = "students.csv";

    public StudentManagementSystem() {
        students = new ArrayList<>();
    }

    public void addStudent(String id, String name) {
        students.add(new Student(id, name));
        saveStudentsToCSV(); // 自动保存
    }

    public void recordGrade(String studentId, String courseCode, double score) {
        Student student = findStudent(studentId);
        if (student != null) {
            student.addGrade(courseCode, score);
            saveStudentsToCSV(); // 自动保存
        }
    }

    public Student findStudent(String id) {
        return students.stream()
                .filter(s -> s.getId().equals(id))
                .findFirst()
                .orElse(null);
    }

    public void saveStudentsToCSV() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(CSV_FILE_PATH))) {
            writer.write("ID,姓名,课程成绩,GPA\n"); // 写入标题行
            for (Student student : students) {
                writer.write(student.toString());
                writer.newLine();
            }
            System.out.println("学生信息已保存到 CSV 文件中。");
        } catch (IOException e) {
            System.out.println("保存失败: " + e.getMessage());
        }
    }

    public void displayGPA(String gpaId) {
        Student student = findStudent(gpaId);
        if (student != null) {
            System.out.printf("学生 %s 的 GPA: %.2f%n", student.getName(), student.calculateGPA());
        }
    }

    public void exportGrades() {
        for (Student student : students) {
            System.out.println("学生 " + student.getName() + " 的成绩:");
            student.getGrades().forEach((course, score) -> {
                System.out.printf("课程: %s, 成绩: %.2f%n", course, score);
            });
        }
    }

    public static void main(String[] args) {
        StudentManagementSystem system = new StudentManagementSystem();

        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("1. 添加学生");
            System.out.println("2. 录入成绩");
            System.out.println("3. 查询GPA");
            System.out.println("4. 导出所有成绩并保存到CSV");
            System.out.println("5. 退出");
            System.out.print("选择操作: ");
            int choice = scanner.nextInt();
            scanner.nextLine(); // 处理换行符

            switch (choice) {
                case 1:
                    System.out.print("输入学生ID: ");
                    String id = scanner.nextLine();
                    System.out.print("输入学生姓名: ");
                    String name = scanner.nextLine();
                    system.addStudent(id, name);
                    break;

                case 2:
                    System.out.print("输入学生ID: ");
                    String studentId = scanner.nextLine();
                    System.out.print("输入课程代码: ");
                    String courseCode = scanner.nextLine();
                    System.out.print("输入成绩 (0-100): ");
                    double score = scanner.nextDouble();
                    system.recordGrade(studentId, courseCode, score);
                    break;

                case 3:
                    System.out.print("输入学生ID: ");
                    String gpaId = scanner.nextLine();
                    system.displayGPA(gpaId);
                    break;

                case 4:
                    system.exportGrades();
                    break;

                case 5:
                    System.out.println("退出系统");
                    scanner.close();
                    return;

                default:
                    System.out.println("无效的选择，请重试");
            }
        }
    }
}

